<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\traits\Utils;
use App\Models\PriDeviceInfo;
use Carbon\Carbon;
use DB;
use Illuminate\Http\Request;
use App\Models\Historywarn;
use App\Models\DeviceType;

class DataController extends Controller
{
    use Utils;

    /**
     * @api {get} /data/ 数据列表
     * @apiDescription 数据列表
     * @apiGroup 数据中心
     * @apiPermission none
     * @apiParam {Number} [pdi_index] 设备编号
     * @apiParam {Number} [pageSize=15] 每页显示条数
     * @apiParam {String} table  数据表名
     * @apiParam {String} typeid  设备分类
     * @apiParam {date} rd_updatetime  查询时间
     * @apiSuccess {String} code 状态标志
     * @apiSuccess {String} message 提示信息
     * @apiSuccess {Object[]} data  区域数据
     * @apiSuccessExample {json} 成功:
     *     HTTP/1.1 201
     *     {
     *         "code": 0,
     *         "message": "",
     *          "data": [
     *             {
     *             }
     *          ],
     *          desc: {}
     *     }
     * @apiErrorExample {json} 失败:
     *     HTTP/1.1 422
     *     {
     *       "code": -1,
     *       "message": "错误提示"
     *     }
     */
    public function index(Request $request)
    {
        $perPage = $request->input('pageSize', 15);
        $name = $request->input('pdi_index', '');
        // $table = $request->input('table', '');
        // if (empty($table)) {
        //     return $this->error('表不存在');
        // }
        $dtType = $request->input('typeid', 0);
        if (empty($dtType)) {
            return $this->error('设备类型不存在');
        }
        $info = DeviceType::where('dt_typeid', $dtType)
            ->select(['dt_rtdata_table', 'dt_hisdata_table'])
            ->first();

        if(!$info) {
            return $this->error('设备类型不存在');
        }

        //实时数据或历史数据
        $type = $request->input('type');

        $isReal = $type == 'realdata';
        $table = data_get($info, $isReal?'dt_rtdata_table':'dt_hisdata_table');

        $searchField = 'rd_updatetime';
        if(!$isReal) {
            $searchField = 'hd_datetime';
        }

        $query = DB::table($table);
        if (!empty($name)) {
            $query->where('pdi_index', trim($name));
        }
        $created = $request->input('rd_updatetime', []);
        if (!empty($created)) {
            $query->whereBetween($searchField, $this->formatArrTime($created));
        }
        $columns = $this->getColumnFromTable($table);

        $data = $query->orderBy($searchField, 'desc')->paginate($perPage);

        $desc = $this->getTabelFieldName($dtType);

        $prefix = strpos($table, 'realdata') !== false ? 'rd_' : 'hd_';

        $fieldDesc = $this->formatFields($columns, $desc, $prefix);

        return ['data' => $data, 'desc' => $fieldDesc];
    }


    /**
     * 获取字段描述
     */
    public function getFields(Request $request, $typeid) {

        $dtType = $typeid;
        if (empty($dtType)) {
            return $this->error('设备类型不存在');
        }
        $info = DeviceType::where('dt_typeid', $dtType)
            ->select(['dt_rtdata_table', 'dt_hisdata_table'])
            ->first();

        if(!$info) {
            return $this->error('设备类型不存在');
        }

        //实时数据或历史数据
        $type = $request->input('type');

        $isReal = $type == 'realdata';
        $table = data_get($info, $isReal?'dt_rtdata_table':'dt_hisdata_table');

        $columns = $this->getColumnFromTable($table);

        $dpType=$request->input('dptype', false);

        $desc = $this->getTabelFieldName($dtType, $dpType);

        $prefix = strpos($table, 'realdata') !== false ? 'rd_' : 'hd_';

        $fieldDesc = $this->formatFields($columns, $desc, $prefix);

        return [ 'desc' => $fieldDesc ];

    }
    /**
     * 获取字段定义
     * @param integer $dtTypeid
     * @return array
     */
    protected function getTabelFieldName($dtTypeid, $dpType=false)
    {
        $table = 't_deviceparam';
        $query = DB::table($table);

        if($dpType) {
            $query->where('dp_datatype', $dpType);
        }

        $data = $query->where('dt_typeid', '=', $dtTypeid)
            ->select(['dp_paramname', 'dp_paramdesc'])
            ->get()->toArray();
        if ($data) {
            $data = array_column($data, 'dp_paramdesc', 'dp_paramname');
        }
        return $data;
    }

    /**
     * 格式化字段描述
     * @param array $columns
     * @param array $desc
     * @param string $prefix
     * @return array
     */
    private function formatFields($columns, $desc, $prefix)
    {
        $except = [
            'pdi_index' => ['label' => '设备索引'],
            'hd_index' => ['label' => '索引'],
            'rd_updatetime' => ['label' => '更新时间'],
            'hd_datetime' => ['label' => '创建时间'],
        ];
        if (!$desc) {
            return null;
        }
        $arr = [];
        foreach ($columns as $val) {
            if (array_key_exists($val, $except)) {
                $arr[$val] = $except[$val];
            } else {
                $key = str_replace($prefix, '', $val);
                if (isset($desc[$key])) {
                    $arr[$val] = ['label' => $desc[$key]];
                }
            }
        }
        return $arr;
    }

    //获取6小时数据
    public function data(Request $request)
    {
        $pdi = $request->input('pdi', '');
        $info = PriDeviceInfo::find($pdi);
        if (!$info) {
            $this->error('数据不存在');
        }
        $dtType = $info->dpt_id;

        $model = array_get(config('device.map_tables'), $dtType . '.history');

        if (empty($model)) {
            $this->error('模型不存在');
        }

        $query = DB::table($model)->where('pdi_index', trim($pdi));

        $zhStart = Carbon::now()->subHours(6)->toDateTimeString();

        $zhEnd = Carbon::now()->addHours(1)->toDateTimeString();

        $between = [$zhStart, $zhEnd];

        // $between = ['2018-11-21 12:09:13', '2018-11-21 19:09:29'];

        $data = $query->whereBetween('hd_datetime', $between)->get();

        return ['data' => $data, 'units' => array_get(config('device.units'), $dtType)];
    }

    //获取数据
    protected function getTableData() {
        
    }

    //获取实时数据
    public function real(Request $request)
    {
        $pdi = $request->input('pdi', '');
        $info = PriDeviceInfo::find($pdi);
        if (!$info) {
            $this->error('数据不存在');
        }
        $dtType = $info->dpt_id;

        $table = array_get(config('device.map_tables'), $dtType . '.real');

        if (empty($table)) {
            $this->error('实时表不存在');
        }

        $realData = DB::table($table)->where('pdi_index', trim($pdi))->first();

        $htable = array_get(config('device.map_tables'), $dtType . '.history');

        if (empty($table)) {
            $this->error('历史表不存在');
        }

        $zhStart = Carbon::now()->startOfDay()->toDateTimeString();

        //当天历史数据
        $history = DB::table($htable)->where('pdi_index', trim($pdi))->where('hd_datetime', '>=', $zhStart)->get();

        //告警统计标记
        $isAlarm = $request->input('alarm', 0);

        //当天设备历史告警
        $historyWarn = [];
        $historyWarnCount = [];

        if($isAlarm==1) {
            $company = $info->Co_ID;
            $historyWarn = $this->getAlarmHistory($company, $pdi, $zhStart);
            $historyWarnCount = $this->getAlarmCount($company, $pdi, $zhStart);
        }
        
        return [ 'real' => $realData??[], 'history' => $history, 'dpt_id' => $dtType, 'historyWarn'=>$historyWarn, 'historyCount'=>$historyWarnCount ];
    }


    //统计每日告警次数
    protected function getAlarmCount($company, $pdi, $zhStart) {
        $historyWarn = Historywarn::where('pdi_index', '=', $pdi)
            ->selectRaw("date_format(rs_updatetime, '%Y-%m-%d %H') as hours, count(hw_index) AS num")
            ->where('rs_updatetime', '>=', $zhStart)
            ->where('Rs_status', '=', 1)
            ->where('Co_ID', '=', $company)
            ->groupBy('hours')
            ->get()
            ->pluck('num', 'hours')
            ->toArray();

        $currentHour = date('H');

        $hours = range(0, $currentHour);

        $normHours = collect($hours)->map(function($h)use($historyWarn){
            $date = date('Y-m-d');
            $key = $date.' '.sprintf('%02d', $h);
            $val = array_get($historyWarn, $key, 0);
            return [ 'hours'=>$key, 'num'=> $val];
        })->toArray();

        return $normHours;
    }

    //每日告警历史数据
    protected function getAlarmHistory($company, $pdi, $zhStart) {
        $historyWarn = Historywarn::where('pdi_index', '=', $pdi)
            ->where('rs_updatetime', '>=', $zhStart)
            ->where('Rs_status', '=', 1)
            ->where('Co_ID', '=', $company)
            ->get()
            ->toArray();
        return $historyWarn;
    }

    /**
     * 获取区域数据
     * @param Request $request
     * @return array
     */
    public function area(Request $request) {
        $query = \App\Models\Area::query();
        $user = $request->user();

        $areaId = $user->scope;

        try {
            if($areaId) {
                $query->whereDescendantOrSelf($areaId);
            }
    
            $area = $query->select(['AreaId', 'AreaName', 'Fid', 'Co_ID', 'area_text', '_lft', '_rgt'])
                    ->get()
                    ->toTree()->toArray();
        } catch (\Throwable $th) {
            $area = [];
        }
        

				
		$this->removeEmptyChildren($area);
		

        return [ 'data' => $area ];
    }

    /**
     * 获取公司数据
     * @param Request $request
     * @return array
     */
    public function company(Request $request) {
		
        $company = \App\Models\Company::select(['Co_ID as value', 'Co_Name as label'])
                ->get()
                ->toArray();

        return [ 'data' => $company ];
    }

    /**
     * 获取分类获取设备
     */
    public function devicesByType(Request $request) {
        $cid = $request->input('company');
        $sid = $request->input('site');
        $dptId = $request->input('dpt_id');
        $devices = PriDeviceInfo::select(['pdi_name', 'pdi_index'])
        ->company($cid)
        ->site($sid)
        ->dptId($dptId)
        ->get();

        return [ 'data'=>$devices ];
    }
}
